﻿// -----------------------------------------------------------------------
// <copyright file="TaskExecutor.cs" company="DarkBone">
// DarkBone
// </copyright>
// -----------------------------------------------------------------------

namespace DarkBone.Engine.Tasks
{
   using System;
   using System.Diagnostics;
   using System.IO;

   /// <summary>
   /// Executes given task
   /// </summary>
   public class TaskExecutor
   {
      /// <summary>
      /// Memory Reader
      /// </summary>
      private readonly MemoryReader memReader;

      /// <summary>
      /// Initializes a new instance of the <see cref="TaskExecutor"/> class.
      /// </summary>
      public TaskExecutor()
      {
         this.memReader = new MemoryReader();
      }

      /// <summary>
      /// Executes job for task
      /// </summary>
      /// <param name="task">
      /// The task.
      /// </param>
      /// <exception cref="NotImplementedException">Task.ID not implemented</exception>
      public void Execute(Task task)
      {
         Debug.WriteLine("@@ Executing: " + task.Id);
         switch (task.Id)
         {
            case Task.ID.GetProcess:
               {
                  var currentTask = (TaskGetProcess)task;
                  var processId = 0;
                  currentTask.Result = this.memReader.GetProcess(currentTask.ProcessName, ref processId);
                  currentTask.ProcessId = processId;
               }

               break;
            case Task.ID.ReadMemory:
               {
                  var currentTask = (TaskReadMemory)task;
                  currentTask.Result = this.memReader.ReadMemory(currentTask.AddressToRead, currentTask.Bytes);
               }

               break;
            case Task.ID.ReadMemoryString:
               {
                  var currentTask = (TaskReadMemoryString)task;
                  var value = string.Empty;
                  currentTask.Result = this.memReader.ReadMemory(currentTask.AddressToRead, ref value);
                  currentTask.Value = value;
               }

               break;
            case Task.ID.WriteMemory:
               {
                  var currentTask = (TaskWriteMemory)task;
                  currentTask.Result = this.memReader.WriteMemory(currentTask.AddressToWrite, ref currentTask.Bytes[0]);
               }

               break;
            case Task.ID.GetOpenedFiles:
               {
                  var currentTask = (TaskGetOpenedFiles)task;
                  var p = new Process
                     { StartInfo = { UseShellExecute = false, RedirectStandardOutput = true, FileName = "Handle.exe", Arguments = currentTask.Arguments } };
                  try
                  {
                     p.Start();
                     currentTask.Output = p.StandardOutput.ReadToEnd();
                     p.WaitForExit();
                  }
                  catch (Exception ex)
                  {
                     Debug.WriteLine("GetOpenedFiles", ex);
                  }
               }

               break;
            case Task.ID.OpenMPQ:
               {
                  var currentTask = (TaskOpenMPQ)task;
                  var file = currentTask.Filename.Replace(@"\\", @"\");
                  currentTask.Output = File.Exists(file) ? StormWrapper.ReadMPQMapname(file) : string.Empty;
               }

               break;
            default:
               throw new NotImplementedException("Task.ID not implemented.");
         }
      }
   }
}
